package com.mt.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mt.VO.SelectSeatVO;
import com.mt.constants.Result;
import com.mt.enums.Status;
import com.mt.exception.GlobalException;
import com.mt.feign.OrderApiProvider;
import com.mt.VO.FilmScheduleInfoVO;
import com.mt.mapper.CinemaScheduleMapper;
import com.mt.pojo.CinemaHall;
import com.mt.pojo.CinemaSchedule;
import com.mt.pojo.CinemaSeat;
import com.mt.service.CinemaScheduleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Wang
 * @since 2020-12-11
 */
@Service
@Slf4j
public class CinemaScheduleServiceImpl extends ServiceImpl<CinemaScheduleMapper, CinemaSchedule> implements CinemaScheduleService {
    @Resource
    CinemaScheduleMapper scheduleMapper;

    @Resource
    OrderApiProvider orderApiProvider;


    /**
     * 批量排片
     * */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public List<CinemaSchedule> batchInsertSchedule(List<CinemaSchedule> scheduleList) {
        List<CinemaSchedule> conflictList = CollUtil.newArrayList();
        List<CinemaSchedule> insetList = CollUtil.newArrayList();

        for (CinemaSchedule schedule : scheduleList) {
            List<CinemaSchedule> conflictSchedules = scheduleMapper.exitConflictSchedule(schedule);
            //与数据库无冲突时,验证与insertList中的其他场次是否冲突
            if (conflictSchedules.isEmpty()) {
                if (insetList.size() >= 1 ) {
                    boolean isConflict = false;
                    //判断当前场次与之前已判断可以insert的场次是否冲突
                    for (CinemaSchedule s : insetList) {
                        if (isConflict(schedule, s)) {
                            conflictList.add(schedule);
                            isConflict = true;
                            break;
                        }
                    }
                    if (!isConflict) {
                        insetList.add(schedule);
                    }
                } else {
                    insetList.add(schedule);
                }
            }else{
                conflictList.add(schedule);
            }

        }
        if (!insetList.isEmpty()) {
            boolean insert = scheduleMapper.batchInsert(insetList);
            if (!insert) {
                throw new GlobalException(Status.ERROR,"批量插入失败");
            }
        }
        log.error("冲突列表为:"+ conflictList.toString());
        return conflictList;
    }



    @Override
    public FilmScheduleInfoVO getScheduleDetailInfo(int scheduleId){
        //todo 待校验逻辑完善
        FilmScheduleInfoVO scheduleDetailInfo = scheduleMapper.getScheduleDetailInfo(scheduleId);
        if (scheduleDetailInfo == null){
            throw new GlobalException(Status.NOT_EXIST_SCHDULE);
        }
        return scheduleDetailInfo;
    }

    @Override
    public SelectSeatVO getScheduleSeatsDetail(int scheduleId) {
        //todo 待校验逻辑完善 ,需要修改已经占用的座位状态,available
        SelectSeatVO scheduleSeatsDetail = scheduleMapper.getScheduleSeatsDetail(scheduleId);
        Result result = orderApiProvider.getSoldSeatIdList(scheduleId);
        List<Integer> soldSeats = CollUtil.newArrayList();
        if (result.getCode().equals(Status.SUCCESS.getCode())) {
            soldSeats = (List<Integer>) result.getData();
        }else {
            throw new GlobalException(Status.ERROR,"系统繁忙");
        }
        if (!soldSeats.isEmpty()){
            List<CinemaSeat> seatList = scheduleSeatsDetail.getSeatList();
            for (CinemaSeat seat:seatList) {
                if (soldSeats.contains(seat.getId())){
                    seat.setBuyStatus(1);
                }
            }
            scheduleSeatsDetail.setSeatList(seatList);
        }
        return scheduleSeatsDetail;
    }

    /**
    *检查购买时间是否已过
    * @return 过期返回true
   */
    @Override
    public boolean checkScheduleExpire(int scheduleId){
        DateTime now = DateUtil.date();
        CinemaSchedule schedule = scheduleMapper.selectById(scheduleId);
        String date = schedule.getScheduleDate();
        String time = schedule.getStartTime();
        DateTime scheduleDate = DateUtil.parse(date + " "+time);
        System.out.println(scheduleDate.toString() );
        return now.isAfterOrEquals(scheduleDate);
    }

    /**
     * 有冲突返回 true
     * 否则返回 false
     * */
    private boolean isConflict(CinemaSchedule s1, CinemaSchedule s2) {
        int compare = DateUtil.compare(DateUtil.parse(s1.getScheduleDate()), DateUtil.parse(s2.getScheduleDate()));
        if (s1.getHallId().equals(s2.getHallId()) && compare==0) {
            DateTime startTime1 = DateUtil.parse(s1.getStartTime());
            DateTime endTime1 = DateUtil.parse(s1.getEndTime());

            DateTime startTime2 = DateUtil.parse(s2.getStartTime());
            DateTime endTime2 = DateUtil.parse(s2.getEndTime());

            return startTime1.isIn(startTime2, endTime2) && endTime1.isIn(startTime2, endTime2);
        } else {
            return false;
        }
    }

    /**
    * 排片场次信息修改
    * */
    @Override
    public boolean modifySchedule(CinemaSchedule schedule) {
        //todo 已经有购票的情况下的处理
        List<CinemaSchedule> conflictSchedules = scheduleMapper.exitConflictSchedule(schedule);
        if (conflictSchedules == null) {
            scheduleMapper.updateById(schedule);
        } else {
            throw new GlobalException(Status.SCHDULE_HAVE_CONFLICT);
        }
        return true;
    }


    /**
     * 取消场次
     * */
    @Override
    public boolean deleteSchedule(int scheduleId) {
        if (scheduleMapper.deleteById(scheduleId) > 0) {
            return true;
        }else {
            throw new GlobalException(Status.ERROR);
        }
    }


    /**
    * 查询某电影院某天安排的电影场次
    * */
    @Override
    public List<FilmScheduleInfoVO> listScheduleByFilm(int filmId,int cinemaId, String queryTime) {
        if (StrUtil.isBlank(queryTime)) {
            queryTime= DateUtil.now();
        }
        DateTime dateTime = DateUtil.parse(queryTime);
        String date = dateTime.toString("yyyy-MM-dd");
        String time = dateTime.toString("HH:mm:ss");

        List<FilmScheduleInfoVO> schedules = scheduleMapper.getScheduleList(filmId,cinemaId,date,time);
        return schedules;
    }
    @Override
    public IPage<FilmScheduleInfoVO> pageScheduleByCinema(int currentPage, int pageSize,int cinemaId,String filmName){
        IPage<FilmScheduleInfoVO> page = new Page<>(currentPage, pageSize);
        filmName = StrUtil.isBlank(filmName) ? null : "%" + filmName + "%";
        List<FilmScheduleInfoVO> schedules = scheduleMapper.pageScheduleByCinema(page,cinemaId,filmName);
        page.setRecords(schedules);
        return page;
    }

    /**
    * 查询电源厅安排的场次
    * */
    @Override
    public List<CinemaSchedule> listScheduleByHall(int hallId,String scheduleDate) {
        if (StrUtil.isBlank(scheduleDate)) {
            //默认当天
            scheduleDate= DateUtil.date().toString("yyyy-MM-dd");
        }
        List<CinemaSchedule> cinemaSchedules = scheduleMapper.selectList(Wrappers.<CinemaSchedule>lambdaQuery()
                .eq(CinemaSchedule::getHallId, hallId)
                .eq(CinemaSchedule::getScheduleDate, scheduleDate));
        return cinemaSchedules;
    }

    /**
     * 检查电影厅是否可用
     * */
    @Override
    public boolean checkHallAvailable(String scheduleDate,String start, String end, int hallId) {
        List<CinemaHall> availableHalls = scheduleMapper.getAvailableHall(scheduleDate,start, end, hallId);
        return availableHalls.isEmpty();
    }


    public List<CinemaHall> getAvailableHall(String scheduleDate,String start, String end, int cinemaId) {
        List<CinemaHall> halls = scheduleMapper.getAvailableHall(scheduleDate,start, end, cinemaId);
        return halls;
    }

//    public List<String> getScheduleDateList(){
//        scheduleMapper.getScheduleDateList()
//        return ;
//    }

}
